package com.ztsoft.user.utils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author 23517
 * @version 1.0
 * @description 常用正则表达式验证工具类
 * @date 2023/5/9 10:02
 */
public class RegexUtils {
    /**
     * 正则表达式验证字符串
     *
     * @param regex
     * @param str
     * @return
     */
    private static boolean match(String regex, String str) {
        if (null == str || "".equals(str)) {
            return false;
        } else {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(str);
            return m.matches();
        }
    }

    /**
     * 验证Email
     *
     * @param email email地址，格式：i@510blog.cn.com，zhangsan@xxx.com.cn， xxx代表邮件服务商
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean isEmail(String email) {
        String regex = "\\w+@\\w+\\.[a-z]+(\\.[a-z]+)?"; // 复杂匹配
        return match(regex, email);
    }

    /**
     * 验证URL地址
     *
     * @param url 格式：http://blog.csdn.net:80/xyang81/article/details/7705960? 或
     *            http://www.csdn.net:80
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean isUrl(String url) {
        String regex = "(https?://(w{3}\\.)?)?\\w+\\.\\w+(\\.[a-zA-Z]+)*(:\\d{1,5})?(/\\w*)*(\\??(.+=.*)?(&.+=.*)?)?";
        return match(regex, url);
    }

    /**
     * 验证固定电话号码
     *
     * @param phone 电话号码，格式：国家（地区）电话代码 + 区号（城市代码） + 电话号码，如：+8602085588447
     *              <p>
     *              <b>国家（地区） 代码 ：</b>标识电话号码的国家（地区）的标准国家（地区）代码。它包含从 0 到 9
     *              的一位或多位数字， 数字之后是空格分隔的国家（地区）代码。
     *              </p>
     *              <p>
     *              <b>区号（城市代码）：</b>这可能包含一个或多个从 0 到 9 的数字，地区或城市代码放在圆括号——
     *              对不使用地区或城市代码的国家（地区），则省略该组件。
     *              </p>
     *              <p>
     *              <b>电话号码：</b>这包含从 0 到 9 的一个或多个数字
     *              </p>
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean isPhone(String phone) {
        String regex = "(\\+\\d+)?(\\d{3,4}\\-?)?\\d{7,8}$";
        return match(regex, phone);
    }

    /**
     * 验证手机号码（支持国际格式，+86135xxxx...（中国内地），+00852137xxxx...（中国香港））
     *
     * @param mobile 移动、联通、电信运营商的号码段
     *               <p>
     *               移动的号段：134(0-8)、135、136、137、138、139、147（预计用于TD上网卡）
     *               、150、151、152、157（TD专用）、158、159、187（未启用）、188（TD专用）
     *               </p>
     *               <p>
     *               联通的号段：130、131、132、155、156（世界风专用）、185（未启用）、186（3g）
     *               </p>
     *               <p>
     *               电信的号段：133、153、180（未启用）、189
     *               </p>
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean isMobile(String mobile) {
        String regex = "\\d{11}";
        // String regex = "(\\+\\d+)?1[3458]\\d{9}$";
        return match(regex, mobile);
    }

    /**
     * 判断是否为数值
     *
     * @param numeric
     * @return
     */
    public static boolean isNumeric(String numeric) {
        String regex = "^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$";
        return match(regex, numeric);
    }

    /**
     * 验证整数（正整数和负整数）
     *
     * @param digit 一位或多位0-9之间的整数
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean isDigit(String digit) {
        String regex = "\\-?[1-9]\\d+";
        return match(regex, digit);
    }

    /**
     * 验证整数和浮点数（正负整数和正负浮点数）
     *
     * @param decimals 一位或多位0-9之间的浮点数，如：1.23，233.30
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean isDecimals(String decimals) {
        String regex = "\\-?[1-9]\\d+(\\.\\d+)?";
        return match(regex, decimals);
    }

    /**
     * 判断是否为数字字符串
     *
     * @param digit
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean isDigitString(String digit) {
        String regex = "^[0-9]*$";
        return match(regex, digit);
    }

    /**
     * 验证空白字符
     *
     * @param blankSpace 空白字符，包括：空格、\t、\n、\r、\f、\x0B
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean isBlankSpace(String blankSpace) {
        String regex = "\\s+";
        return match(regex, blankSpace);
    }

    /**
     * 验证IP
     *
     * @param ip
     * @return
     */
    public static boolean isIP(String ip) {
        String num = "(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)";
        String regex = "^" + num + "\\." + num + "\\." + num + "\\." + num + "$";
        return match(regex, ip);
    }

    /**
     * <pre>
     * 获取网址 URL 的一级域名
     * http://www.zuidaima.com/share/1550463379442688.htm ->> zuidaima.com
     * </pre>
     *
     * @param url
     * @return
     */
    public static String getDomain(String url) {
        Pattern p = Pattern.compile("(?<=http://|\\.)[^.]*?\\.(com|cn|net|org|biz|info|cc|tv)", Pattern.CASE_INSENSITIVE);
        // 获取完整的域名
        // Pattern p=Pattern.compile("[^//]*?\\.(com|cn|net|org|biz|info|cc|tv)", Pattern.CASE_INSENSITIVE);
        Matcher matcher = p.matcher(url);
        matcher.find();
        return matcher.group();
    }

    /**
     * 验证中文
     *
     * @param chinese 中文字符
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean isChinese(String chinese) {
        String regex = "^[\u4E00-\u9FA5]+$";
        return match(regex, chinese);
    }

    /**
     * 匹配中国邮政编码
     *
     * @param postcode 邮政编码
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean isPostcode(String postcode) {
        String regex = "[1-9]\\d{5}";
        return match(regex, postcode);
    }

    /**
     * 验证车牌号
     *
     * @param chePaiHao
     * @return
     */
    public static boolean isChePaiHao(String chePaiHao) {
        String regex1 = "^[\u4E00-\u9FA5]{1}[a-zA-Z]{1}[a-zA-Z_0-9]{5}$";
        String regex2 = "^使[a-zA-Z_0-9]{6}$";
        String regex3 = "^(BL)[a-zA-Z_0-9]{5}$";
        return match(regex1, chePaiHao) || match(regex2, chePaiHao) || match(regex3, chePaiHao);
    }

    /**
     * 验证日期（年月日）
     *
     * @param birthday 日期，格式：1992-09-03，或1992.09.03
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean isBirthday(String birthday) {
        String regex = "[1-9]{4}([-./])\\d{1,2}\\1\\d{1,2}";
        return match(regex, birthday);
    }

    /**
     * 验证用户名,用户名只能由6到15位数字、字母、下划线组成!
     *
     * @param username
     * @return
     */
    public static boolean username(String username) {
        String regex = "^([a-z]|[A-Z])[\\w]{6,20}$";
        return match(regex, username);
    }

    /**
     * 验证中文姓名,两到四个汉字!
     *
     * @param trueName
     * @return
     */
    public static boolean trueName(String trueName) {
        String regex = "^[\u4e00-\u9fa5]{2,4}$";
        return match(regex, trueName);
    }

    /**
     * 验证密码,表示以匹配字母开头（不区分大小写），随后字符以字母、数字、下划线组成，长度 6 到 20 位
     *
     * @param password
     * @return
     */
    public static boolean password(String password) {
        String regex = "^([a-z]|[A-Z])[\\w]{6,20}$";
        return match(regex, password);
    }

    /**
     * 验证会员卡号,5129008866XXXXX
     *
     * @param kh
     * @return
     */
    public static boolean isHuiYuanKaHao(String kh) {
        String regex = "^(5129008866)[0-9]{6}$";
        return match(regex, kh);
    }

    /**
     * 验证输入身份证号
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isIdCard(String str) {
        // String regex = "(^\\d{18}$)|(^\\d{15}$)";
        // return match(regex, str);
        return str.length() == 18;
    }

    /**
     * 验证男女性别
     *
     * @param sex 待验证的字符串
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean checkSex(String sex) {
        String regex = "^(男|女){1}$";
        return match(regex, sex);
    }

    /**
     * 判断str 是否是一个合法的Long型
     *
     * @param str
     * @return
     */
    public static boolean isLong(String str) {
        try {
            Long.parseLong(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }
}